package com.netsdk.lht2.push;

import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import com.netsdk.demo.util.sql.Trajectory;
import com.netsdk.lht2.util.LogUtil;
import com.netsdk.lht2.util.TrajectoryUtil;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.*;

public final class PushClient {

    private Socket socket;
    private final LogUtil logUtil = new LogUtil("push");
    private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4);
    private final ConcurrentHashMap<String, List<String>> data = new ConcurrentHashMap<>();

    private final Cache<String, RoadDataStatistic> data2 = CacheUtil.newFIFOCache(1000);

    public PushClient() throws IOException {
        createSocket();
        executorService.scheduleAtFixedRate(() -> data2.forEach(RoadDataStatistic::printAddTimeInfo),60,60,TimeUnit.SECONDS);

    }
    private void createSocket() throws IOException {
        socket = new Socket("127.0.0.1",8091);
    }

    private boolean testSocket(){
        return socket.isConnected() && !socket.isClosed() && !socket.isInputShutdown() && !socket.isOutputShutdown();
    }

    private synchronized Socket obtatinSocket() throws IOException {
        if (testSocket()){
        }else {
            createSocket();
        }
        return socket;
    }

    public void push(String utc,String channel,String nLane,Trajectory[] arr) throws Exception {
        if (arr == null){
            return ;
        }
        List<String> arrs = data.get(utc);
        String body = TrajectoryUtil.toPushStringArr(arr);
        if (arrs == null){
            arrs = new ArrayList<>();
            arrs.add(body);
            data.put(utc,arrs);
            int delay = 50;
            executorService.schedule(new PushRunnable(utc),delay, TimeUnit.SECONDS);

        }else{
            arrs.add(body);
        }
    }


    public synchronized void push2(String utc,String channel,String nLane,List<Trajectory[]> arr) throws Exception {
        if (arr == null){
            return ;
        }
        RoadDataStatistic roadDataStatistic = data2.get(utc);
        if (roadDataStatistic == null){
            roadDataStatistic = new RoadDataStatistic(utc);
            roadDataStatistic.addData(channel,nLane,arr);
            data2.put(utc,roadDataStatistic);
            System.out.println("提交时间："+ LocalDateTime.now()+"; utc: "+utc);
            executorService.schedule(new PushRunnable(utc),55, TimeUnit.SECONDS);

            CurrentTaskInfo currentTaskInfo = new CurrentTaskInfo();
            currentTaskInfo.utc = utc;
            currentTaskInfo.submitTime = LocalDateTime.now();
        }else{
            roadDataStatistic.addData(channel,nLane,arr);
        }
    }

    class CurrentTaskInfo{
        private String utc;
        private LocalDateTime submitTime;
        private LocalDateTime exectTime;
    }


     class PushRunnable implements Runnable{
        private String utc;

        public PushRunnable(String utc) {
            this.utc = utc;
        }

//        @Override
//        public void run() {
//            List<String> arrs = data.get(utc);
//            StringBuilder sb = new StringBuilder();
//            for (String arr : arrs) {
//                sb.append(arr);
//            }
//            System.out.println("数据量："+(arrs.size()) + " 时间："+ utc);
//            try{
//                Socket socket = obtatinSocket();
//                OutputStream os = socket.getOutputStream();
//                String body = sb.toString();
//                body += "\n";
//                os.write(body.getBytes(StandardCharsets.UTF_8));
//                os.flush();
//                // 写入日志
//                logUtil.log(String.format("插入数据,时间：,data: %s" ,new Date(),body));
//                data.remove(utc);
//            }catch (Exception e){
//                e.printStackTrace();
//                try {
//                    socket.close();
//                    createSocket();
//                }catch (Exception b){}
//            }
//        }

         @Override
         public void run() {
             String utc = getUtc();
             RoadDataStatistic roadDataStatistic = data2.get(utc);
             try{
//                 if(roadDataStatistic == null){
//                     System.out.println("时间丢失");
//                     roadDataStatistic = new RoadDataStatistic(utc);
//                     data2.put(utc,roadDataStatistic);
//                 }
                 System.out.println("执行时间："+ LocalDateTime.now());
                 String body = roadDataStatistic.getPushData();
                 if(!body.equals("")){
                     Socket socket = obtatinSocket();
                     OutputStream os = socket.getOutputStream();
                     body += "\n";
                     os.write(body.getBytes(StandardCharsets.UTF_8));
                     os.flush();
                     // 写入日志
                     System.out.println("推送数据："+ utc);
                     logUtil.log(String.format("插入数据,时间：%s,data: %s" ,new Date(),body));
                     data.remove(this.utc);
                 }
             }catch (Exception e){
                 e.printStackTrace();
                 try {
                     socket.close();
                     createSocket();
                 }catch (Exception b){}
             }
         }

         private String getUtc(){
            String currentUtc = utc;
//             LocalDateTime utcTime = TimeCacheUtil.parseUtc(utc);
//             utc = TimeCacheUtil.formateLocalDateTime(utcTime.plusMinutes(1));
             return currentUtc;
         }
    }





}
